package com.effective.java.comparable;

import java.math.BigInteger;

public class SimpleComparableImpl_01 implements Comparable<SimpleComparableImpl_01> {

	private final BigInteger value;

	SimpleComparableImpl_01(BigInteger value) {

		if (value == null) {
			throw new IllegalArgumentException("Mandatory input parameter 'value' is null!");
		}
		this.value = value;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int compareTo(SimpleComparableImpl_01 object) {

		return this.value.compareTo(object.value);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int hashCode() {

		return 17 * 37 * this.value.intValue();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean equals(Object object) {

		if (this == object) {
			return true;
		}

		if (!(object instanceof SimpleComparableImpl_01)) {
			return false;
		}

		return this.value.equals(((SimpleComparableImpl_01) object).value);
	}

	public BigInteger getValue() {

		return this.value;
	}

	public static void main(String[] args) {

		SimpleComparableImpl_01 w = new SimpleComparableImpl_01(BigInteger.valueOf(1L));
		SimpleComparableImpl_01 x = new SimpleComparableImpl_01(BigInteger.valueOf(1L));
		SimpleComparableImpl_01 y = new SimpleComparableImpl_01(BigInteger.valueOf(2L));
		SimpleComparableImpl_01 z = new SimpleComparableImpl_01(BigInteger.valueOf(3L));

		// ensure 'x.compareTo(y)' == '- y.compareTo(x)'
		System.out.println("Check if: " + x.getValue() + ".compareTo(" + y.getValue() + ") == -" + y.getValue()
				+ ".compareTo(" + x.getValue() + ")");
		if (x.compareTo(y) != -y.compareTo(x)) {
			throw new RuntimeException("'x.compareTo(y)' != '- y.compareTo(x)'!");
		}

		// ensure 'z.compareTo(y) > 0' AND 'y.compareTo(x) > 0' implies
		// 'z.compareTo(x) > 0
		System.out.println("Check if: " + z.getValue() + ".compareTo(" + y.getValue() + ") > 0 AND " + y.getValue()
				+ ".compareTo(" + x.getValue() + ") > 0 => " + z.getValue() + ".compareTo(" + x.getValue() + ") > 0");
		if (z.compareTo(y) > 0 && y.compareTo(x) > 0) {
			if (z.compareTo(x) <= 0) {
				throw new RuntimeException("Transitivity is not ensured!");
			}
		}

		// ensure 'w.compareTo(x) == 0' => 'w.compareTo(y)' == 'x.compareTo(y)'
		System.out.println("Check if: " + w.getValue() + ".compareTo(" + x.getValue() + ") == 0 => " + w.getValue()
				+ ".compareTo(" + y.getValue() + ") == " + x.getValue() + ".compareTo(" + y.getValue() + ")");
		if (w.compareTo(x) == 0) {
			if (x.compareTo(y) != w.compareTo(y)) {
				throw new RuntimeException(
						"'w.compareTo(x) == 0' => 'w.compareTo(y)' == 'x.compareTo(y)' is not ensured!");
			}
		}

		// ensure 'w.compareTo(x) == 0' => 'w.equals(x) == true'
		System.out.println("Check if: " + w.getValue() + ".compareTo(" + x.getValue() + ") == 0 => " + w.getValue()
				+ ".equals(" + x.getValue() + ") == true");
		if (w.compareTo(x) == 0) {
			if (!w.equals(x)) {
				throw new RuntimeException("'w.compareTo(x) == 0' => 'w.equals(x) == true' is not ensured!");
			}
		}
	}
}
